﻿using System;
using System.Collections.Generic;
using System.Xml;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using Microsoft.Surface.Core;
using Microsoft.Surface.Presentation;
using Microsoft.Surface.Presentation.Controls;
using ESRI.ArcGIS.Client.Geometry;
using System.Windows.Shapes;

namespace ENMAX_ArcGIS
{
    /// <summary>
    /// The ScatterView layer that holds MapFrames,
    /// GhostFrames, and TroubleTicketListFrames.
    /// This class contains functions that allows
    /// the creation and deletion of the above objecs.
    /// </summary>
    public class TwoPointScatterView : ScatterView
    {
        // Keep a reference to the underlying background map
        // so that MapFrames and GhostFrames knows
        // where they should be positioned on the screen
        private ArcGisMap backgroundLayerMap;

        public TwoPointScatterView()
        {
            Loaded += new RoutedEventHandler(OnLoaded);
            Unloaded += new RoutedEventHandler(OnUnloaded);
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
        }

        private void OnUnloaded(object sender, RoutedEventArgs e)
        {
        }

        /// <summary>
        /// Register the underlying background map
        /// to this ScatterView layer so that this
        /// class knows where to position the MapFrames
        /// relative to the screen.
        /// </summary>
        /// <param name="backgroundMap"></param>
        public void RegisterBackgroundMap(ArcGisMap backgroundMap)
        {
            backgroundLayerMap = backgroundMap;
        }

        /// <summary>
        /// Removes a MapFrame, if it already exists
        /// in this ScatterView.
        /// </summary>
        /// <param name="deleteMap"></param>
        public void RemoveMap(MapFrame deleteMap)
        {
            if (Items.Contains(deleteMap))
            {
                Items.Remove(deleteMap);
                Items.Remove(deleteMap.GetGhostFrame());
            }
        }

        /// <summary>
        /// Removes a TroubleTicketListFrame, if it
        /// already exists in this ScatterView.
        /// </summary>
        /// <param name="deleteFrame"></param>
        public void RemoveTroubleTicketListFrame(TroubleTicketListFrame deleteFrame)
        {
            if (Items.Contains(deleteFrame))
                Items.Remove(deleteFrame);
        }

        public void AddMapTip(ArcGisMapTip mapTip, Point screen_point, double orientation)
        {
            mapTip.Orientation = orientation;
            mapTip.Center = screen_point;

            Items.Add(mapTip);
        }

        /// <summary>
        /// Adds a new MapFrame to the ScatterView via the
        /// two map points from the map.
        /// 
        /// A MapFrame is created where the extent are defined
        /// by the two points (one for upper left corner and the
        /// other for lower right corner).
        /// 
        /// The position of the MapFrame on the screen is also defined
        /// by the 2 Points value (one for upper left corner and another
        /// for lower right corner).
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="point1"></param>
        /// <param name="point2"></param>
        public void CreateMapFrameFromMapPoints(MapPoint p1, MapPoint p2, Point point1, Point point2)
        {

            SolidColorBrush randomColor = GetRandomColor();

            GhostFrame gFrame = new GhostFrame(backgroundLayerMap, new Envelope(p1, p2), randomColor);
            MapFrame mFrame = new MapFrame(this, gFrame, p1, p2, randomColor);

            MapLayersManager.MapLayerAddedDelegate delegate1 = new MapLayersManager.MapLayerAddedDelegate(mFrame.MapLayerAdded);
            MapLayersManager.MapLayerDeletedDelegate delegate2 = new MapLayersManager.MapLayerDeletedDelegate(mFrame.MapLayerDeleted);
            MapLayersManager.Instance.MapLayerAdded += delegate1;
            MapLayersManager.Instance.MapLayerDeleted += delegate2;

            mFrame.Orientation = 0.0;
            mFrame.Height = Math.Abs(point1.Y - point2.Y);
            mFrame.Width = Math.Abs(point1.X - point2.X);
            mFrame.Center = new System.Windows.Point(point1.X + (point2.X - point1.X) / 2, point1.Y + (point2.Y - point1.Y) / 2);
            
            Items.Add(gFrame);
            Items.Add(mFrame);
           
        }

        /// <summary>
        /// Adds a new MapFrame to the ScatterView via the
        /// TroubleTicketPins.
        /// 
        /// The position of the MapFrame (centre) is the
        /// same as the related TroubleTicketPin.  The 
        /// orientation of the frame is also defined. The
        /// map extent of the frame is the same as the
        /// related TroubleTicket.
        /// </summary>
        /// <param name="tTicket"></param>
        /// <param name="centerPt"></param>
        /// <param name="orientation"></param>
        public void CreateMapFrameFromTroublePin(TroubleTicket tTicket, Point centerPt, double orientation)
        {
            /* if it is already open, dont open again */
            if (tTicket.MapFrameCurrentlyOpen == true)
            {
                // bring to front
                GetMapFrame(tTicket).IsActive = true;
                return;
            }

            Envelope mapExtent = new Envelope();
            double frameHeight = 270;
            double frameWidth = 270;
            Point frameCenter = new Point();
            double frameOri = orientation + 90;

            if (tTicket.MapFramePreviouslyOpen == true)
            {
                mapExtent = tTicket.MapFrameEnvelope;
                frameHeight = tTicket.MapFrameHeight;
                frameWidth = tTicket.MapFrameWidth;
                frameCenter = tTicket.MapFrameCenter;
                frameOri = tTicket.MapFrameOrientation;
            }
            else
            {
                mapExtent = tTicket.MapFrameEnvelope;
                //frameHeight = height;
                //frameWidth = width;
                frameCenter = centerPt;
            }
            SolidColorBrush randomColor = GetRandomColor();
            GhostFrame gFrame = new GhostFrame(backgroundLayerMap, mapExtent, randomColor);
            MapFrame mFrame = new MapFrame(this, gFrame, mapExtent, randomColor);

            MapLayersManager.MapLayerAddedDelegate delegate1 = new MapLayersManager.MapLayerAddedDelegate(mFrame.MapLayerAdded);
            MapLayersManager.MapLayerDeletedDelegate delegate2 = new MapLayersManager.MapLayerDeletedDelegate(mFrame.MapLayerDeleted);
            MapLayersManager.Instance.MapLayerAdded += delegate1;
            MapLayersManager.Instance.MapLayerDeleted += delegate2;

            mFrame.RelatedTroubleTicket = tTicket;
            mFrame.Orientation = frameOri;
            mFrame.Height = frameHeight;
            mFrame.Width = frameWidth;
            mFrame.Center = frameCenter;

            tTicket.MapFrameCurrentlyOpen = true;

            Items.Add(gFrame);
            Items.Add(mFrame);

        }

        /// <summary>
        /// This is called when user clicks on a TroubleTicket from
        /// the TroubleTicketListFrame.  A MapFrame is created that
        /// represents the TroubleTicket that was selected.
        /// </summary>
        /// <param name="tTicket"></param>
        /// <param name="centerPt"></param>
        /// <param name="orientation"></param>
        public void CreateMapFrameFromTroubleTicketList(TroubleTicket tTicket, Point centerPt, double orientation)
        {
            /* if it is already open, dont open again */
            if (tTicket.MapFrameCurrentlyOpen == true)
            {
                // bring to front
                MapFrame mp = GetMapFrame(tTicket);
                mp.IsActive = true;
                return;
            }

            Envelope mapExtent = tTicket.MapFrameEnvelope;
            double frameHeight = 270;
            double frameWidth = 270;
            double frameOri = orientation + 90;

            SolidColorBrush randomColor = GetRandomColor();
            GhostFrame gFrame = new GhostFrame(backgroundLayerMap, mapExtent, randomColor);
            MapFrame mFrame = new MapFrame(this, gFrame, mapExtent, randomColor);

            MapLayersManager.MapLayerAddedDelegate delegate1 = new MapLayersManager.MapLayerAddedDelegate(mFrame.MapLayerAdded);
            MapLayersManager.MapLayerDeletedDelegate delegate2 = new MapLayersManager.MapLayerDeletedDelegate(mFrame.MapLayerDeleted);
            MapLayersManager.Instance.MapLayerAdded += delegate1;
            MapLayersManager.Instance.MapLayerDeleted += delegate2;

            mFrame.RelatedTroubleTicket = tTicket;
            mFrame.Orientation = frameOri;
            mFrame.Height = frameHeight;
            mFrame.Width = frameWidth;
            mFrame.Center = centerPt;

            tTicket.MapFrameCurrentlyOpen = true;

            Items.Add(gFrame);
            Items.Add(mFrame);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="pt"></param>
        /// <param name="orientation"></param>
        public TroubleTicketListFrame AddTroubleTicketListFrame(Point pt, double orientation)
        {
            TroubleTicketListFrame ttlFrame = new TroubleTicketListFrame(this, pt, orientation);

            Items.Add(ttlFrame);

            return ttlFrame;
        }

        /// <summary>
        /// This method will handle the functionality
        /// when the "Search" button is clicked.
        /// </summary>
        /// <param name="loc"></param>
        public void AddSearchBox(Point loc)
        {
            //ScatterViewItem container = new ScatterViewItem();
            //SurfaceKeyboard.CenterX = (float)loc.X;
            //SurfaceKeyboard.CenterY = (float)loc.Y;
            //SurfaceKeyboard.IsVisible = true;
            //AddMapAnnotation(loc);

        }

       
        /// <summary>
        /// Randomly generates a colour for a new
        /// MapFrame
        /// </summary>
        /// <returns></returns>
        private SolidColorBrush GetRandomColor()
        {
            /* 
             * Randomly generate a color
             * 
             * byte r = represents the red byte
             * byte g = the green byte
             * byte b = blue byte
             */
            Random rnd = new Random();
            byte r = Convert.ToByte(rnd.Next(0, 255));
            byte g = Convert.ToByte(rnd.Next(0, 255));
            byte b = Convert.ToByte(rnd.Next(0, 255));
            return new SolidColorBrush(Color.FromRgb(r, g, b));
        }

        /// <summary>
        /// Search for the MapFrame in this
        /// ScatterView that is related to the
        /// given TroubleTicket.  If the MapFrame
        /// exists, return it, otherwise, return
        /// null.
        /// </summary>
        /// <param name="tTicket"></param>
        /// <returns></returns>
        public MapFrame GetMapFrame(TroubleTicket tTicket)
        {
            for (int i = 0; i < Items.Count; i++)
            {
                if (Items.GetItemAt(i) is MapFrame)
                {
                    MapFrame mp = Items.GetItemAt(i) as MapFrame;
                    if (mp.RelatedTroubleTicket == tTicket)
                        return mp;

                }
            }
            return null;
        }

    }
}
